#include "pwm.h"
#include <cstdio>
extern "C" {
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
}

using namespace std;

int pwm::pwm_config(const char *attr, const char *val)
{
    char file_path[100]{};
    int len;
    int fd;

    sprintf(file_path, "%s/%s", pwm_path, attr);
    if (0 > (fd = open(file_path, O_WRONLY))) {
        perror("open error");
        return fd;
    }

    len = strlen(val);
    if (len != write(fd, val, len)) {
        perror("write error");
        close(fd);
        return -1;
    }

    close(fd);  //关闭文件
    return 0;
}

pwm::pwm(QObject *parent,qint8 pwm_sec,qint8 duty,qint64 period) : QObject(parent)
{
    qint64 duty_tmp = static_cast<qint32>(((float)duty*0.01 * period));
    /* 导出pwm */
    sprintf(pwm_path, "/sys/class/pwm/pwmchip%u/pwm0",pwm_sec);
    if (access(pwm_path, F_OK)) {//如果pwm0目录不存在, 则导出

        char temp[100];
        int fd;

        sprintf(temp, "/sys/class/pwm/pwmchip%u/export", pwm_sec);
        if (0 > (fd = open(temp, O_WRONLY))) {
            perror("open error");
            exit(-1);
        }

        if (1 != write(fd, "0", 1)) {//导出pwm
            perror("write error");
            close(fd);
            exit(-1);
        }

        close(fd);  //关闭文件
    }
    /* 配置周期 */
    if(this->pwm_config("period",QString::number(period).toLatin1()))
    {
        printf("period config error\n");
        exit(-1);
    }
    /* 配置占空比 */
    if(this->pwm_config("duty_cycle",QString::number(duty_tmp).toLatin1()))
    {
        printf("duty config error\n");
        exit(-1);
    }
    /* 使能PWM */
    this->pwm_config("enable","1");
}

pwm::~pwm()
{
    /* 失能PWM */
    this->pwm_config("enable","0");
    /* 删除PWM */
    this->pwm_config("unexport","0");}
